/**
 * @file lcd_display.cpp
 * @brief Implementation of functions for controlling an LCD display.
 */

// ==================================================
// =============== INCLUDE ==========================
// ==================================================

#include "lcd_display.h"

// ==================================================
// =============== PRE-DECLARE ======================
// ==================================================

LV_IMG_DECLARE(img_bg_text_480x480)
LV_FONT_DECLARE(lv_font_yahei_16)
extern int lcd_mode;
extern int last_lcd_mode;

// ==================================================
// =============== STATIC VARIABLES =================
// ==================================================

static String title = "Hello world, achdu0000!";

// ==================================================
// =============== STATIC FUNCTION ==================
// ==================================================

/**
 * 111
 */
inline static void log_cb(const char *buf);

/**
 * 222
 */
static void display_init();

/**
 * the junior part of our course design
 */
static void create_junior_part();

#ifdef SENIOR_PART_OF_DESIGN
/**
 * the senior part of our course design
 */
static void create_senior_part();
#endif

// ==================================================
// =============== IMPLEMENTATION ===================
// ==================================================

inline static void log_cb(const char *buf)
{
#if LV_USE_LOG
    _LCD_DISPLAY_LOG_SERIAL.println(buf);
#endif
}

static void display_init()
{

#if LV_USE_LOG
    lv_log_register_print_cb(log_cb);
#endif

    String log_msg = title + "starting";
    LV_LOG_INFO(log_msg.c_str());

    LV_LOG_INFO("Init panel device");

    ESP_Panel *panel = new ESP_Panel();
    panel->init();

#if LVGL_PORT_AVOID_TEAR
    // When avoid tearing function is enabled, configure the RGB bus according to the LVGL configuration
    ESP_PanelBus_RGB *rgb_bus = static_cast<ESP_PanelBus_RGB *>(panel->getLcd()->getBus());
    rgb_bus->configRgbFrameBufferNumber(LVGL_PORT_DISP_BUFFER_NUM);
    rgb_bus->configRgbBounceBufferSize(LVGL_PORT_RGB_BOUNCE_BUFFER_SIZE);
#endif

    panel->begin();

    LV_LOG_INFO("Init LVGL");
    lvgl_port_init(panel->getLcd(), panel->getTouch());
}

static void create_junior_part()
{
    lv_obj_t *screen = lv_scr_act();
    lv_obj_clear_flag(screen, LV_OBJ_FLAG_SCROLLABLE);
    junior_part_on_create(screen);
}

#ifdef SENIOR_PART_OF_DESIGN
static void create_senior_part()
{
    // change to senior part
    last_lcd_mode = lcd_mode;
    lcd_mode = 2;
    
    lv_obj_t *screen = lv_scr_act();
    lv_obj_clear_flag(screen, LV_OBJ_FLAG_SCROLLABLE);
    // lv_obj_set_style_radius(screen, LV_RADIUS_CIRCLE, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_border_width(screen, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    // lv_obj_set_style_border_opa(screen,LV_OPA_TRANSP,LV_PART_MAIN| LV_STATE_DEFAULT);
    lv_obj_set_style_bg_color(screen, SCREEN_BG_COLOR, LV_PART_MAIN | LV_STATE_DEFAULT);
    
    senior_part_on_create(screen);
}
#endif

void display_on_create()
{
    // change to junior part
    last_lcd_mode = lcd_mode;
    lcd_mode = 1;
    
    display_init();

    LV_LOG_INFO("Create UI");
    /** Lock the mutex due to the LVGL APIs are not thread-safe */
    lvgl_port_lock(-1);

    create_junior_part();

    /** Release the mutex */
    lvgl_port_unlock();

    String log_msg = title + "ending";
    LV_LOG_INFO(log_msg.c_str());
}

#ifdef SENIOR_PART_OF_DESIGN
void switch_to_senior_part()
{
    lv_obj_t *src = lv_scr_act();
    lv_obj_t *new_scr = lv_obj_create(NULL);
    lv_scr_load(new_scr);

    create_senior_part();
}
#endif